#include <stdio.h>

int my_strlen(const char * str)
{
	const char *eos = str;

	while (*eos++);

	return (eos - str - 1);
}

int main()
{
	return my_strlen("xiaozhi");
}

#if 0

mov eax, dword ptr _str$[ebp]	; 将指针指向字符串
mov dword ptr _eos[ebp], eax	; 指向局部变量eos
mov ecx, dword ptr _eos$[ebp]	; ECX=eos

movsx edx, byte ptr [ecx]		
mov eax, dword ptr eos$[ebp]	; eax = eos
add eax, 1						; eax++
mov dword ptr _eos$[ebp], eax	; eax 还原为 eos
test edx, edx					; edx == 0 ?


movsx , mov with sign-extend。在把小空间数据转换为大空间数据时，存在填充高位数据的问题。如将原始数据的8位数据
填写充EDX的低8位：原始数据是负数，该指令将使用1填充第8到第31位（高24），否则使用0填充高24位。

/* GCC */

not ecx

not对操作数的所有位(bit)都进行非运算。和xor ecx, 0xffffffff等价。 not ecx 的结果与某数相加，相当于某数减去ECX和1。

在程度开始的时候，ECX保存了字符串首个字符的地址（指针），EAX存储的是终止符的地址。对ECX求非，再与EAX相加，
就是在计算EAX-ECX-1的值。这种运算可以得到正确的字符串长度。

#endif

#if 0
/*
 * intel
 */
0000000000001129 <my_strlen>:
    1129:	f3 0f 1e fa          	endbr64 
    112d:	55                   	push   %rbp
    112e:	48 89 e5             	mov    %rsp,%rbp
    1131:	48 89 7d e8          	mov    %rdi,-0x18(%rbp)
    1135:	48 8b 45 e8          	mov    -0x18(%rbp),%rax
    1139:	48 89 45 f8          	mov    %rax,-0x8(%rbp)
    113d:	90                   	nop
    113e:	48 8b 45 f8          	mov    -0x8(%rbp),%rax
    1142:	48 8d 50 01          	lea    0x1(%rax),%rdx
    1146:	48 89 55 f8          	mov    %rdx,-0x8(%rbp)
    114a:	0f b6 00             	movzbl (%rax),%eax
    114d:	84 c0                	test   %al,%al
    114f:	75 ed                	jne    113e <my_strlen+0x15>
    1151:	48 8b 45 f8          	mov    -0x8(%rbp),%rax
    1155:	48 2b 45 e8          	sub    -0x18(%rbp),%rax
    1159:	83 e8 01             	sub    $0x1,%eax
    115c:	5d                   	pop    %rbp
    115d:	c3                   	retq   

000000000000115e <main>:
    115e:	f3 0f 1e fa          	endbr64 
    1162:	55                   	push   %rbp
    1163:	48 89 e5             	mov    %rsp,%rbp
    1166:	48 8d 3d 97 0e 00 00 	lea    0xe97(%rip),%rdi        # 2004 <_IO_stdin_used+0x4>
    116d:	e8 b7 ff ff ff       	callq  1129 <my_strlen>
    1172:	5d                   	pop    %rbp
    1173:	c3                   	retq   
    1174:	66 2e 0f 1f 84 00 00 	nopw   %cs:0x0(%rax,%rax,1)
    117b:	00 00 00 
    117e:	66 90                	xchg   %ax,%ax

/*
 * arm
 */
000000000040051c <my_strlen>:
  40051c:	d10083ff 	sub	sp, sp, #0x20
  400520:	f90007e0 	str	x0, [sp, #8]
  400524:	f94007e0 	ldr	x0, [sp, #8]
  400528:	f9000fe0 	str	x0, [sp, #24]
  40052c:	d503201f 	nop
  400530:	f9400fe0 	ldr	x0, [sp, #24]
  400534:	91000401 	add	x1, x0, #0x1
  400538:	f9000fe1 	str	x1, [sp, #24]
  40053c:	39400000 	ldrb	w0, [x0]
  400540:	7100001f 	cmp	w0, #0x0
  400544:	54ffff61 	b.ne	400530 <my_strlen+0x14>  // b.any
  400548:	f9400fe1 	ldr	x1, [sp, #24]
  40054c:	f94007e0 	ldr	x0, [sp, #8]
  400550:	cb000020 	sub	x0, x1, x0
  400554:	51000400 	sub	w0, w0, #0x1
  400558:	910083ff 	add	sp, sp, #0x20
  40055c:	d65f03c0 	ret

0000000000400560 <main>:
  400560:	a9bf7bfd 	stp	x29, x30, [sp, #-16]!
  400564:	910003fd 	mov	x29, sp
  400568:	90000000 	adrp	x0, 400000 <_init-0x3b0>
  40056c:	9118c000 	add	x0, x0, #0x630
  400570:	97ffffeb 	bl	40051c <my_strlen>
  400574:	a8c17bfd 	ldp	x29, x30, [sp], #16
  400578:	d65f03c0 	ret
  40057c:	00000000 	.inst	0x00000000 ; undefined


#endif

